package db;

import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Map;

import parsing.Category;
//import parsing.Person;
import core.City;
import core.Continent;
import core.Country;
import core.User;

public class DB_Simulation extends DB_Abstract {

	//################### Constructors ###################################
	
	//empty constructor
	public DB_Simulation(){
	}
	
	
	//################### Overridden Connection Functions ################
	
	@Override
	public int connect() {
		SimulateData();
		return 1;
	}
	

	@Override
	public int closeConnection() {
		return 1;
	}
	




	public void SimulateData(){
		
	  //Define 3 Cities   - London, Paris, Chicago
       City city = new City("London", (float)51.507222,  (float) -0.1275,  1,  1);
       cities.add(city);
       city = new City("Paris", (float)48.8567,  (float) 2.3508,  3,  2);
       cities.add(city);
       city = new City("Chicago", (float)41.88414,  (float) -87.632379,  2,  3);
       cities.add(city);
       
       //Define 3 Countries - England, USA, France
       Country country = new Country(1 , 1,"England");
       countries.add(country);
       country = new Country(2, 2 ,"USA");
       countries.add(country);
       country = new Country(1, 3,"France");
       countries.add(country);
       
       //Define 3 Continents - Europe, North-America, Asia
       Continent Cont = new Continent("Europe", 1);
       continents.add(Cont);
       Cont = new Continent("North-America", 2);
       continents.add(Cont);
       Cont = new Continent("Asia", 3);
       continents.add(Cont);
       
       //Define 3 People - Europe, North-America, Asia
       Person per = new Person("Harrison Ford", 2, 3, -1);
       persons.put(per.getName(), per);
       per = new Person("Jim Morrison", 3, -1, 2);
       persons.put(per.getName(), per);
       per = new Person("Tony Adams", 1, 1, 2);
       persons.put(per.getName(), per);
       
       //Define 3 Categories
       Category cat = new Category(1, "SportsMan");
       categories.add(cat);
       cat = new Category(2, "Actor");
       categories.add(cat);
       cat = new Category(3, "Singer");
       categories.add(cat);
       
       //Define 3 Categories
       User admin = new User(users.size() + 1, "Guy Castel", "Aa123456");
       users.add(admin);
       User Hen = new User(users.size() + 1, "Hen BB", "Bb123456");
       users.add(Hen);
       User Hila = new User(users.size() + 1, "Hila Mosacho", "Cc123456");
       users.add(Hila);
       User Elad = new User(users.size() + 1, "EladSpira", "QAZqaz123");
       users.add(Elad);

	
       
	}


	//################### Overridden DB Functions ######################
	
	
	//################### Add Data Functions ###################################
	
	@Override
	public int addNewCountry(Country newCountry) {
		countries.add(newCountry);
		return 1;
	}
	
	@Override
	public int addNewPerson(Person newPerson) {
		newPerson.setID(HashSample(newPerson.getName()));
		persons.put(newPerson.getName(), newPerson);
		return 1;
	}
	
	@Override
	public int addNewCity(City newCity) {
		cities.add(newCity);
		return 1;
	}
	
	@Override
	public int addNewCategory(String CatName) {

		int id = categories.size();
		Category cat = new Category(id, CatName);
		addNewCategory(cat);
		return 1;
	}
	
	@Override
	public int addNewUser(User user) {
		users.add(user);
		return 1;
	}


	//### Verify if are needed at all
	@Override
	public int addNewPersonFromList(Map<String, Person> persons) {
		Collection<Person> newPeople = persons.values(); 
		for (Person newPerson : newPeople){
			persons.put(newPerson.getName(), newPerson);
		}
		return 1;
	}
	
	@Override
	public int addNewCityFromList(LinkedList<City> newCities) {
		for (City newCity : newCities){
			cities.add(newCity);
		}
		return 1;
	}
	
	public int addNewCategory(Category Cat) {

		categories.add(Cat);
		return 1;
	}
	
	
	//################### Remove Data Functions ###################################

	@Override
	public int removeCountry(int ID){
		for (int i = 0; i < countries.size(); i ++){
			if (ID == countries.get(i).getCountryId())
				countries.remove(i);
		}
		return 1;
	}
	
	@Override
	public int removePerson(Person per) {
		persons.remove(per.getName());
		return 1;
	}
	
	@Override
	public int removeCategory(int ID) {
		for (int i = 0; i < categories.size(); i ++){
			if (ID == categories.get(i).getCategoryID())
				categories.remove(i);
		}
		return 1;
	}
	
	@Override
	public int removeCity(int ID) {
		for (int i = 0; i < cities.size(); i ++){
			if (ID == cities.get(i).getCityId())
			cities.remove(i);
		}
		return 1;
	}

	@Override
	public int removeUser(int userID) {
		for (int i = 0; i < users.size(); i ++){
			if (userID == users.get(i).getID()){
				users.remove(i);
				return 1;
			}
		}
		return 0;
	}
	
	//#################### Modify Data Functions ####################################
	



	@Override
	public int modifyCity(int cityID, String newName) {

		
		getCity(cityID).setCityName(newName);
		
		return 1;
	}

	@Override
	public int modifyPerson(Person oldPer, Person newPer) {

		newPer.setID(oldPer.getID());
		removePerson(oldPer);
		addNewPerson(newPer);
		
		return 1;
	}
	
	@Override
	public int modifyCountry(Country Cat, String newName) {

		removeCountry(Cat);
		Cat.setCountryName(newName);
		addNewCountry(Cat);
		return 1;
	}

	@Override
	public int modifyCategory(Category Cat, String newName) {
		removeCategory(Cat);
		Cat.setCategoryName(newName);
		addNewCategory(Cat);
		return 1;
	}
	
	@Override
	public int modifyUser(String oldUserName, User newUser) {

		
		User oldUser = getUser(oldUserName);
		newUser.setID(oldUser.getID());
		removeUser(oldUser);
		addNewUser(newUser);
		return 1;
	}
	
	//#################### Get Data Functions ####################################
	
	//Basic


	@Override
	public Continent getContinent(int continentID) {
		for (int i = 0; i < continents.size(); i ++){
			if (continentID == continents.get(i).getContinentId())
				return  continents.get(i);
		}
		return new Continent("-1", -1);
	}
	
	@Override
	public Country getCountry(int countryID) {
		
		for (int i = 0; i < countries.size(); i ++){
			if (countryID == countries.get(i).getCountryId())
				return  countries.get(i);
		}
		return new Country(-1 , -1,"-1");
	}
	
	@Override
	public City getCity(int cityID) {
		for (int i = 0; i < cities.size(); i++){
			if (cityID == cities.get(i).getCityId())
				return  cities.get(i);
		}
		return new City("-1" , -1, -1, -1, -1);
	}

	@Override
	public Category getCategory(int categoryID) {
		for (int i = 0; i < categories.size(); i ++){
			if (categoryID == categories.get(i).getCategoryID())
				return  categories.get(i);
		}
		return new Category(-1, "-1");
	}
	
	@Override
	public Person getPerson(String name) {
		if (!persons.containsKey(name))
			return new Person("-1", -1, -1, -1); // To avoid NULL
		return persons.get(name);
	}

	@Override
	public Person getPerson(int ID) {
		Collection<Person> personTemp = persons.values();
		Iterator<Person> personIter = personTemp.iterator();
		Person perTemp;
		while (personIter.hasNext()){
			perTemp = personIter.next();
			if (ID == perTemp.getID())
				return perTemp;
		}
		return new Person("-1", -1, -1, -1);
	}


	
	@Override
	public User getUser(int userID) {
		for (int i = 0; i < users.size(); i++){
			if (userID == users.get(i).getID())
				return  users.get(i);
		}
		return new User( "-1", "-1");
	}
	
	@Override
	public User getUser(String userName) {
		for (int i = 0; i < users.size(); i++){
			if (userName.equals(users.get(i).getName()))
				return  users.get(i);
		}
		return new User( "-1", "-1");
	}
	






	//Advance
	@Override
	public LinkedList<City> getCitiesFromCountry(int countryID) {
		
		LinkedList<City> citiesNew = new LinkedList<City>();
		for (int i = 0; i < cities.size(); i++){
			if (countryID == cities.get(i).getCountryId())
				citiesNew.add(cities.get(i));
		}
	     Collections.sort(citiesNew, new Comparator<City>() {
	         @Override
	         public int compare(City o1, City o2) {
	             return o1.getCityName().compareTo(o2.getCityName());
	         }
	     });
		return citiesNew;
	}

	
	
	//################### Setters and Getters ###################################



}
